/**
 * 判断初始化复杂json多层数据-使用js数据类型默认值
 * processJsonData 函数的主要目的是处理 JSON 数据，将其中的 null 值根据 typeConfig 中指定的默认值进行替换。
 * @param {string|object} jsonData - 需要处理的 JSON 数据，可以是 JSON 字符串或者 JavaScript 对象。
 * @param {object} typeConfig - 配置对象，用于指定 jsonData 中各个字段的默认值。
 * @returns {object|null} - 处理后的 JavaScript 对象，如果解析失败则返回 null。
 */
export function processJsonData(jsonData, typeConfig) {
  // 检查 typeConfig 是否为有效的对象，若不是则输出错误信息并返回 null
  if (typeof typeConfig !== 'object' || typeConfig === null) {
    console.error('typeConfig 必须是一个对象');
    return null;
  }

  let data;
  try {
    // 若 jsonData 是字符串，尝试将其解析为 JavaScript 对象；若本身是对象则直接使用
    data = typeof jsonData === 'string' ? JSON.parse(jsonData) : jsonData;
  } catch (error) {
    // 处理 JSON 解析失败的情况，输出错误信息并返回 null
    console.error('JSON 解析失败:', error);
    return null;
  }

  /**
   * 递归遍历对象，将 null 值替换为默认值
   * @param {object} obj - 需要处理的对象
   * @param {object} config - 当前层级对应的配置对象
   * @returns {object} - 处理后的对象
   */
  function traverseAndInit(obj, config) {
    // 使用 Object.keys 遍历对象的自有属性，避免遍历原型链上的属性
    Object.keys(obj).forEach(key => {
      // 获取当前键对应的值
      const value = obj[key];
      // 获取该键在当前配置对象中对应的默认值
      const defaultValue = config ? config[key] : undefined;
      // 如果值为 null 且默认值存在，则将值替换为默认值
      if (value === null && defaultValue !== undefined) {
        obj[key] = defaultValue;
      }
      // 如果值是对象且不为 null，则递归调用 traverseAndInit 处理该对象
      else if (typeof value === 'object' && value !== null) {
        // 获取该键在当前配置对象中对应的子配置对象
        const subConfig = config ? config[key] : {};
        traverseAndInit(value, subConfig);
      }
    });
    // 返回处理后的对象
    return obj;
  }

  // 调用 traverseAndInit 函数处理数据并返回结果
  return traverseAndInit(data, typeConfig);
}


/**
 * 判断初始化复杂json多层数据-对象+数组-使用js数据类型默认值
 * processJsonData 函数的主要目的是处理 JSON 数据，将其中的 null 值根据 typeConfig 中指定的默认值进行替换。
 * @param {string|object} jsonData - 需要处理的 JSON 数据，可以是 JSON 字符串或者 JavaScript 对象。
 * @param {object} typeConfig - 配置对象，用于指定 jsonData 中各个字段的默认值。
 * @returns {object|null} - 处理后的 JavaScript 对象，如果解析失败则返回 null。
 */
export function processJsonData(jsonData, typeConfig) {
  // 检查 typeConfig 是否为有效的对象，若不是则输出错误信息并返回 null
  if (typeof typeConfig !== 'object' || typeConfig === null) {
    console.error('typeConfig 必须是一个对象');
    return null;
  }

  let data;
  try {
    // 若 jsonData 是字符串，尝试将其解析为 JavaScript 对象；若本身是对象则直接使用
    data = typeof jsonData === 'string' ? JSON.parse(jsonData) : jsonData;
  } catch (error) {
    // 处理 JSON 解析失败的情况，输出错误信息并返回 null
    console.error('JSON 解析失败:', error);
    return null;
  }

  /**
   * 对象+数组，递归遍历对象，将 null 值替换为默认值
   * @param {object|Array} obj - 需要处理的对象或数组
   * @param {object|Array} config - 当前层级对应的配置对象或数组
   * @returns {object|Array} - 处理后的对象或数组
   */
  function traverseAndInit(obj, config) {
    if (Array.isArray(obj)) {
      obj.forEach((item, index) => {
        let subConfig;
        if (Array.isArray(config)) {
          // 循环使用 config 数组中的元素
          subConfig = config[index % config.length];
        } else {
          subConfig = config;
        }
        if (typeof item === 'object' && item !== null) {
          traverseAndInit(item, subConfig);
        } else if (item === null && subConfig !== undefined) {
          obj[index] = subConfig;
        }
      });
    } else if (typeof obj === 'object' && obj !== null) {
      Object.keys(obj).forEach(key => {
        const value = obj[key];
        const defaultValue = config ? config[key] : undefined;
        if (value === null && defaultValue !== undefined) {
          obj[key] = defaultValue;
        } else if (typeof value === 'object' && value !== null) {
          const subConfig = config ? config[key] : {};
          traverseAndInit(value, subConfig);
        }
      });
    }
    return obj;
  }

  // 调用 traverseAndInit 函数处理数据并返回结果
  return traverseAndInit(data, typeConfig);
}


